package main

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"log"
	"sync"
	"time"
)

type DBConn struct {
	Lock     sync.Mutex
	DirLock  sync.Mutex
	SerLock  sync.Mutex
	MakLock  sync.Mutex
	LabLock  sync.Mutex
	movies   map[string]int
	director map[int]string
	series   map[int]string
	maker    map[int]string
	label    map[int]string
	conn     *sql.DB
	preStmt  map[string]*sql.Stmt
}

// 名字检索
type symbol struct {
	id int
	en string
	jp string
}

// 演员
type actress struct {
	id     int
	aid    int
	name   string
	nameJP string
	movies int
	avatar string
}

// 电影
type movie struct {
	cid        string
	fcid       string
	title      string
	sample     int
	duration   int
	introduce  string
	seriesId   int
	directorId int
	labelId    int
	makerId    int
	pics       int
	ps         string
	pl         string
	su         string
	saleAt     string
	soldAt     int64
	filled     int
}

var mDB = &DBConn{
	preStmt: make(map[string]*sql.Stmt),
}
var symbols []symbol

// 获取数据库连接
func (db *DBConn) getConn() *sql.DB {
	if nil == db.conn {
		log.Println("【getConn】")
		conn, err := sql.Open("mysql", "root:@/spider")
		if err != nil {
			panic(err.Error())
		}
		for {
			if err = conn.Ping(); err == nil {
				break
			} else {
				log.Println("DB getConn failed")
				time.Sleep(5 * time.Second)
			}
		}
		db.conn = conn
	}
	return db.conn
}

//--------------movies-------------//

// 获取影片查询句柄
func (db *DBConn) getCheckStmt() *sql.Stmt {
	if _, ok := db.preStmt["movieQur"]; !ok {
		log.Println("【getCheckStmt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `id` FROM movies WHERE cid=?"); err == nil {
			db.preStmt["movieQur"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["movieQur"]
}

// 获取未填充的电影
func (db *DBConn) getMoviesUnfilled() *sql.Stmt {
	if _, ok := db.preStmt["movieUnfilled"]; !ok {
		log.Println("【getMoviesUnfilled】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `cid` FROM movies WHERE filled IN (0,4) LIMIT ?"); err == nil {
			db.preStmt["movieUnfilled"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["movieUnfilled"]
}
func (db *DBConn) GetScanMovies(count int) (res []string) {
	rows, err := db.getMoviesUnfilled().Query(count)
	if err != nil {
		//log.Println(err)
		return
	}

	var cid string
	for rows.Next() {
		rows.Scan(&cid)
		res = append(res, cid)
	}
	return
}

// 获取新增影片句柄
func (db *DBConn) getInsertMovieStmt() *sql.Stmt {
	if _, ok := db.preStmt["movieIns"]; !ok {
		log.Println("【getInsertMovieStmt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO movies (`cid`) VALUE (?)"); err == nil {
			db.preStmt["movieIns"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["movieIns"]
}

// 获取更新影片句柄
func (db *DBConn) getUpdateMovieStmt() *sql.Stmt {
	if _, ok := db.preStmt["movieUpt"]; !ok {
		log.Println("【getUpdateMovieStmt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE movies SET `title`=?,`sample`=?,`duration`=?,`introduce`=?,`series_id`=?," +
			"`director_id`=?,`label_id`=?,`maker_id`=?,`pics`=?,`ps`=?,`pl`=?,`su`=?,`sale_at`=?,`filled`=?,`fcid`=?,`sold_at`=? WHERE `cid`=?");
			err == nil {
			db.preStmt["movieUpt"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["movieUpt"]
}

// 判断影片是否已存在
func (db *DBConn) IsMovieExist(cid string) bool {
	db.Lock.Lock()
	defer db.Lock.Unlock()
	if db.movies == nil || len(db.movies) <= 0 {
		db.movies = make(map[string]int)
		conn := db.getConn()
		if rows, err := conn.Query("SELECT `cid`,`id` FROM movies"); err == nil {
			for rows.Next() {
				k, v := "", 0
				rows.Scan(&k, &v)
				db.movies[k] = v
			}
		}
	}
	_, exist := db.movies[cid]
	if exist {
		return true
	}
	return false
}

// 预新增电影
func (db *DBConn) PreInsertMovie(cid string) bool {
	db.Lock.Lock()
	if db.movies == nil || len(db.movies) <= 0 {
		db.movies = make(map[string]int)
	}
	db.movies[cid] = 1
	db.Lock.Unlock()

	_, err := db.getInsertMovieStmt().Exec(cid)
	if err != nil {
		log.Println(err)
		return false
	}
	return true
}

// 更新电影
func (db *DBConn) UpdateMovie(mv *movie) bool {
	_, err := db.getUpdateMovieStmt().Exec(mv.title, mv.sample, mv.duration, mv.introduce, mv.seriesId, mv.directorId,
		mv.labelId, mv.makerId, mv.pics, mv.ps, mv.pl, mv.su, mv.saleAt, mv.filled, mv.fcid, mv.soldAt, mv.cid)
	if err != nil {
		log.Println(err)
		return false
	}
	return true
}

// 获取更新filled句柄
func (db *DBConn) getMovieFilledStmt() *sql.Stmt {
	if _, ok := db.preStmt["movieUPFilled"]; !ok {
		log.Println("【movieUPFilled】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE movies SET `filled` = ? WHERE `cid`=?"); err == nil {
			db.preStmt["movieUPFilled"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["movieUPFilled"]
}

// 更新filled
func (db *DBConn) UptMovieFilled(fi int, cid string) {
	_, err := db.getMovieFilledStmt().Exec(fi, cid)
	if err != nil {
		log.Println(err)
		return
	}
}

// 获取名字检索列表
func (db *DBConn) GetShortCid(id int) (ll []string) {
	conn := db.getConn()
	rows, err := conn.Query("SELECT `cid` FROM movies WHERE id > ? ORDER BY id LIMIT 1000", id)
	if err != nil {
		//log.Println(err)
		return
	}

	for rows.Next() {
		s := ""
		err = rows.Scan(&s)
		if err != nil {
			panic(err.Error())
		}
		ll = append(ll, s)
	}
	return
}

// 电影关联分类
func (db *DBConn) getMG() *sql.Stmt {
	if _, ok := db.preStmt["insertMG"]; !ok {
		log.Println("【getMG】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO m_genre (`cid`,`gid`) VALUE (?,?)"); err == nil {
			db.preStmt["insertMG"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["insertMG"]
}
func (db *DBConn) InsertMG(gid int, cid string) {
	_, err := db.getMG().Exec(cid, gid)
	if err != nil {
		log.Println(err)
	}
}

// 电影关联演员
func (db *DBConn) getMA() *sql.Stmt {
	if _, ok := db.preStmt["insertMA"]; !ok {
		log.Println("【getMA】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO m_actress (`cid`,`aid`) VALUE (?,?)"); err == nil {
			db.preStmt["insertMA"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["insertMA"]
}
func (db *DBConn) InsertMA(aid int, cid string) {
	_, err := db.getMA().Exec(cid, aid)
	if err != nil {
		log.Println(err)
	}
}

// 获取无演员电影
func (db *DBConn) getFailedMA(start int) (ids []string, last int) {
	conn := db.getConn()
	rows, err := conn.Query("SELECT movies.cid,movies.id FROM movies LEFT JOIN m_actress ON movies.cid=m_actress.cid WHERE "+
		"movies.id < ? AND isnull(m_actress.aid) ORDER BY movies.id DESC LIMIT 1000", start)
	if err != nil {
		return
	}

	for rows.Next() {
		cid := ""
		_ = rows.Scan(&cid, &last)
		ids = append(ids, cid)
	}
	return
}

// ---------symbol----------//

// 获取名字检索列表
func (db *DBConn) GetNameKeys() {
	conn := db.getConn()
	rows, err := conn.Query("SELECT * FROM symbol")
	if err != nil {
		//log.Println(err)
		return
	}
	//columns, err := rows.Columns()
	symbols = nil

	for rows.Next() {
		s := symbol{}
		err = rows.Scan(&s.id, &s.en, &s.jp)
		if err != nil {
			panic(err.Error())
		}
		symbols = append(symbols, s)
	}
}

//---------演员 actress---------//

// 获取新建演员句柄
func (db *DBConn) getActorIns() *sql.Stmt {
	if _, ok := db.preStmt["actorIns"]; !ok {
		log.Println("【actorIns】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO actress (`aid`,`name`,`name_jp`,`movies`,`avatar`) VALUE (?,?,?,?,?)"); err == nil {
			db.preStmt["actorIns"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["actorIns"]
}

// 获取演员查询句柄
func (db *DBConn) getActorQur() *sql.Stmt {
	if _, ok := db.preStmt["actorQur"]; !ok {
		log.Println("【actorQur】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `name` FROM actress WHERE aid=?"); err == nil {
			db.preStmt["actorQur"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["actorQur"]
}

// 获取演员名字
func (db *DBConn) GetActressNameByID(aid int) (name string) {
	err := db.getActorQur().QueryRow(aid).Scan(&name) // WHERE number = 13
	if err != nil {
		//log.Println(err)
	}
	return
}

// 新增演员
func (db *DBConn) InsertActress(act *actress) bool {
	_, err := db.getActorIns().Exec(act.aid, act.name, act.nameJP, act.movies, act.avatar)
	if err != nil {
		log.Println(err)
		return false
	}
	return true
}

// 获取演员查询句柄
func (db *DBConn) getActorUpt() *sql.Stmt {
	if _, ok := db.preStmt["actorUpt"]; !ok {
		log.Println("【actorUpt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE actress SET `movies` = ? WHERE `aid`=?"); err == nil {
			db.preStmt["actorUpt"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["actorUpt"]
}

func (db *DBConn) getActorStatusUpt() *sql.Stmt {
	if _, ok := db.preStmt["actorStatusUpt"]; !ok {
		log.Println("【actorStatusUpt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE actress SET `off` = 1 WHERE `aid`=?"); err == nil {
			db.preStmt["actorStatusUpt"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["actorStatusUpt"]
}

// 更新演员电影数量
func (db *DBConn) UptActressMovies(aid, movies int) {
	_, err := db.getActorUpt().Exec(movies, aid)
	if err != nil {
		log.Println(err)
		return
	}
}

// 演员已退役
func (db *DBConn) UptActressStatus(aid int) {
	_, err := db.getActorStatusUpt().Exec(aid)
	if err != nil {
		log.Println(err)
		return
	}
}

// 获取未扫描影片的演员
func (db *DBConn) getScanActorStmt() *sql.Stmt {
	if _, ok := db.preStmt["actorScan"]; !ok {
		log.Println("【actorScan】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `aid`,`movies` FROM actress WHERE `off` = 0 ORDER BY `scan_at` LIMIT ?"); err == nil {
			db.preStmt["actorScan"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["actorScan"]
}
func (db *DBConn) GetScanActor(count int) (res []actress) {
	rows, err := db.getScanActorStmt().Query(count)
	if err != nil {
		//log.Println(err)
		return
	}

	var act actress
	for rows.Next() {
		rows.Scan(&act.aid, &act.movies)
		res = append(res, act)
	}
	return
}

// 更新演员电影扫描时间
func (db *DBConn) getActorScanUpt() *sql.Stmt {
	if _, ok := db.preStmt["actorScanUpt"]; !ok {
		log.Println("【actorScanUpt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE actress SET `scan_at` = ? WHERE `aid`=?"); err == nil {
			db.preStmt["actorScanUpt"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["actorScanUpt"]
}

// 更新演员电影扫描时间
func (db *DBConn) UptActressScan(aid int, scanAt string) {
	_, err := db.getActorScanUpt().Exec(scanAt, aid)
	if err != nil {
		log.Println(err)
		return
	}
}

// 获取不在籍演员
func (db *DBConn) getMissActress() (actress []int) {
	conn := db.getConn()
	rows, err := conn.Query("SELECT aid FROM actress_in")
	if err != nil {
		return
	}

	for rows.Next() {
		aid := 0
		_ = rows.Scan(&aid)
		actress = append(actress, aid)
	}
	return
}

//---------分类 genre---------//

// 获取新增分类句柄
func (db *DBConn) getGenreIns() *sql.Stmt {
	if _, ok := db.preStmt["genreIns"]; !ok {
		log.Println("【genreIns】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO genre (`gid`,`genre`) VALUE (?,?)"); err == nil {
			db.preStmt["genreIns"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["genreIns"]
}

// 获取分类句柄
func (db *DBConn) getGenreQur() *sql.Stmt {
	if _, ok := db.preStmt["genreQur"]; !ok {
		log.Println("【genreQur】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `genre` FROM genre WHERE gid=?"); err == nil {
			db.preStmt["genreQur"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["genreQur"]
}

// 新增分类
func (db *DBConn) InsertGenre(gid int, genre string) bool {
	_, err := db.getGenreIns().Exec(gid, genre)
	if err != nil {
		log.Println(err)
		return false
	}
	return true
}

// 获取分类
func (db *DBConn) GetGenreByID(gid int) (genre string) {
	err := db.getGenreQur().QueryRow(gid).Scan(&genre)
	if err != nil {
		//log.Println(err)
	}
	return
}

//---------制片 Maker---------//

// 获取新增制片句柄
func (db *DBConn) getMakerIns() *sql.Stmt {
	if _, ok := db.preStmt["makerIns"]; !ok {
		log.Println("【makerIns】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO maker (`mid`,`maker`,`logo`,`slogan`) VALUE (?,?,?,?)"); err == nil {
			db.preStmt["makerIns"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["makerIns"]
}

// 新增制片
func (db *DBConn) InsertMaker(mid int, maker, logo, slogan string) bool {
	db.MakLock.Lock()
	if db.maker == nil || len(db.maker) <= 0 {
		db.maker = make(map[int]string)
	}
	db.maker[mid] = maker
	db.MakLock.Unlock()

	_, err := db.getMakerIns().Exec(mid, maker, logo, slogan)
	if err != nil {
		log.Println(err)
		return false
	}
	return true
}

// 判断系列是否已存在
func (db *DBConn) IsMakerExist(mid int) bool {
	db.MakLock.Lock()
	defer db.MakLock.Unlock()
	if db.maker == nil || len(db.maker) <= 0 {
		db.maker = make(map[int]string)
		conn := db.getConn()
		if rows, err := conn.Query("SELECT `mid`,`maker` FROM maker"); err == nil {
			for rows.Next() {
				var k int
				var v string
				rows.Scan(&k, &v)
				db.maker[k] = v
			}
		}
	}
	_, exist := db.maker[mid]
	if exist {
		return true
	}
	return false
}

// 获取未扫描影片的制片
func (db *DBConn) getScanMakerStmt() *sql.Stmt {
	if _, ok := db.preStmt["makerScan"]; !ok {
		log.Println("【makerScan】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `mid` FROM maker WHERE status=1 ORDER BY `scan_at` LIMIT ?"); err == nil {
			db.preStmt["makerScan"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["makerScan"]
}
func (db *DBConn) GetScanMaker(count int) (res []int) {
	rows, err := db.getScanMakerStmt().Query(count)
	if err != nil {
		//log.Println(err)
		return
	}

	var mid int
	for rows.Next() {
		rows.Scan(&mid)
		res = append(res, mid)
	}
	return
}

// 更新制片电影扫描时间
func (db *DBConn) getMakerScanUpt() *sql.Stmt {
	if _, ok := db.preStmt["makerScanUpt"]; !ok {
		log.Println("【makerScanUpt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE maker SET `scan_at` = ? WHERE `mid`=?"); err == nil {
			db.preStmt["makerScanUpt"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["makerScanUpt"]
}
func (db *DBConn) UptMakerScan(mid int, scanAt string) {
	_, err := db.getMakerScanUpt().Exec(scanAt, mid)
	if err != nil {
		log.Println(err)
		return
	}
}

// 更新制片状态
func (db *DBConn) uptMakerStatus() *sql.Stmt {
	if _, ok := db.preStmt["uptMakerStatus"]; !ok {
		log.Println("【uptMakerStatus】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE maker SET `status` = 2 WHERE `mid`=?"); err == nil {
			db.preStmt["uptMakerStatus"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["uptMakerStatus"]
}
func (db *DBConn) UptMakerStatus(mid int) {
	_, err := db.uptMakerStatus().Exec( mid)
	if err != nil {
		log.Println(err)
		return
	}
}

//---------系列 Series---------//

// 获取新增系列句柄
func (db *DBConn) getSeriesIns() *sql.Stmt {
	if _, ok := db.preStmt["seriesIns"]; !ok {
		log.Println("【seriesIns】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO series (`sid`,`series`) VALUE (?,?)"); err == nil {
			db.preStmt["seriesIns"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["seriesIns"]
}

// 判断系列是否已存在
func (db *DBConn) IsSeriesExist(sid int) bool {
	db.SerLock.Lock()
	defer db.SerLock.Unlock()
	if db.series == nil || len(db.series) <= 0 {
		log.Print("IsSeriesExist | IsSeriesExist")
		db.series = make(map[int]string)
		conn := db.getConn()
		if rows, err := conn.Query("SELECT `sid`,`series` FROM series"); err == nil {
			for rows.Next() {
				var k int
				var v string
				rows.Scan(&k, &v)
				db.series[k] = v
			}
		}
	}
	_, exist := db.series[sid]
	if exist {
		return true
	}
	return false
}

// 新增系列
func (db *DBConn) InsertSeries(sid int, series string) bool {
	db.SerLock.Lock()
	if db.series == nil || len(db.series) <= 0 {
		db.series = make(map[int]string)
	}
	db.series[sid] = series
	db.SerLock.Unlock()

	_, err := db.getSeriesIns().Exec(sid, series)
	if err != nil {
		log.Println(err)
		return false
	}
	return true
}

// 获取未扫描影片的系列
func (db *DBConn) getScanSeriesStmt() *sql.Stmt {
	if _, ok := db.preStmt["seriesScan"]; !ok {
		log.Println("【seriesScan】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `sid` FROM series WHERE status=1 ORDER BY `scan_at` LIMIT ?"); err == nil {
			db.preStmt["seriesScan"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["seriesScan"]
}
func (db *DBConn) GetScanSeries(count int) (res []int) {
	rows, err := db.getScanSeriesStmt().Query(count)
	if err != nil {
		//log.Println(err)
		return
	}

	var sid int
	for rows.Next() {
		rows.Scan(&sid)
		res = append(res, sid)
	}
	return
}

// 更新系列电影扫描时间
func (db *DBConn) getSeriesScanUpt() *sql.Stmt {
	if _, ok := db.preStmt["seriesScanUpt"]; !ok {
		log.Println("【seriesScanUpt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE series SET `scan_at` = ? WHERE `sid`=?"); err == nil {
			db.preStmt["seriesScanUpt"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["seriesScanUpt"]
}
func (db *DBConn) UptSeriesScan(sid int, scanAt string) {
	_, err := db.getSeriesScanUpt().Exec(scanAt, sid)
	if err != nil {
		log.Println(err)
		return
	}
}

// 更新系列状态
func (db *DBConn) getSeriesStatusUpt() *sql.Stmt {
	if _, ok := db.preStmt["getSeriesStatusUpt"]; !ok {
		log.Println("【getSeriesStatusUpt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE series SET `status` = 2 WHERE `sid`=?"); err == nil {
			db.preStmt["getSeriesStatusUpt"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["getSeriesStatusUpt"]
}
func (db *DBConn) UptSeriesStatus(sid int) {
	_, err := db.getSeriesStatusUpt().Exec(sid)
	if err != nil {
		log.Println(err)
		return
	}
}

//--------pics down----------//
func (db *DBConn) getPicsIns() *sql.Stmt {
	if _, ok := db.preStmt["picsIns"]; !ok {
		log.Println("【picsIns】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO pics (`path`,`url`,`mark`) VALUE (?,?,?)"); err == nil {
			db.preStmt["picsIns"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["picsIns"]
}

func (db *DBConn) AddPicDown(mark, path, url string) int64 {
	res, err := db.getPicsIns().Exec(path, url, mark)
	if err != nil {
		log.Println(err)
		return 0
	}
	id, _ := res.LastInsertId()
	return id
}

func (db *DBConn) getPicsUpt() *sql.Stmt {
	if _, ok := db.preStmt["picsUpt"]; !ok {
		log.Println("【picsUpt】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE pics SET `down`=1,`small`=? WHERE `id`=?"); err == nil {
			db.preStmt["picsUpt"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["picsUpt"]
}

func (db *DBConn) UpdatePicDown(id, small int) {
	_, err := db.getPicsUpt().Exec(small, id)
	if err != nil {
		log.Println(err)
		return
	}
	return
}

func (db *DBConn) getWillingDownStmt() *sql.Stmt {
	if _, ok := db.preStmt["picsDown"]; !ok {
		log.Println("【picsDown】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `id`,`path`,`url` FROM pics WHERE `down`=0 AND `id`>0 LIMIT ?"); err == nil {
			db.preStmt["picsDown"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["picsDown"]
}

func (db *DBConn) GetWillingDown(count int) (res []string) {
	rows, err := db.getWillingDownStmt().Query(count)
	if err != nil {
		//log.Println(err)
		return
	}

	var pic, id, path, url string
	for rows.Next() {
		rows.Scan(&id, &path, &url)
		pic = id + "|" + path + "|" + url
		res = append(res, pic)
	}
	return
}

//--------Director----------//

// 判断导演是否已存在
func (db *DBConn) IsDirectorExist(did int) bool {
	db.DirLock.Lock()
	defer db.DirLock.Unlock()
	if db.director == nil || len(db.director) <= 0 {
		log.Print("IsDirectorExist | IsDirectorExist")
		db.director = make(map[int]string)
		conn := db.getConn()
		if rows, err := conn.Query("SELECT `did`,`director` FROM director"); err == nil {
			for rows.Next() {
				var k int
				var v string
				rows.Scan(&k, &v)
				db.director[k] = v
			}
		}
	}
	_, exist := db.director[did]
	if exist {
		return true
	}
	return false
}

func (db *DBConn) getDirectorIns() *sql.Stmt {
	if _, ok := db.preStmt["directorIns"]; !ok {
		log.Println("【directorIns】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO director (`did`,`director`) VALUE (?,?)"); err == nil {
			db.preStmt["directorIns"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["directorIns"]
}

func (db *DBConn) AddDirector(did int, director string) int64 {
	db.DirLock.Lock()
	if db.director == nil || len(db.director) <= 0 {
		db.director = make(map[int]string)
	}
	db.director[did] = director
	db.DirLock.Unlock()

	res, err := db.getDirectorIns().Exec(did, director)
	if err != nil {
		log.Println(err)
		return 0
	}

	id, _ := res.LastInsertId()
	return id
}

//--------Label----------//

func (db *DBConn) IsLabelExist(lid int) bool {
	db.LabLock.Lock()
	defer db.LabLock.Unlock()
	if db.label == nil || len(db.label) <= 0 {
		log.Print("IsLabelExist | IsLabelExist")
		db.label = make(map[int]string)
		conn := db.getConn()
		if rows, err := conn.Query("SELECT `lid`,`label` FROM label"); err == nil {
			for rows.Next() {
				var k int
				var v string
				rows.Scan(&k, &v)
				db.label[k] = v
			}
		}
	}
	_, exist := db.label[lid]
	if exist {
		return true
	}
	return false
}

func (db *DBConn) getLabelIns() *sql.Stmt {
	if _, ok := db.preStmt["labelIns"]; !ok {
		log.Println("【labelIns】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("INSERT INTO label (`lid`,`label`) VALUE (?,?)"); err == nil {
			db.preStmt["labelIns"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["labelIns"]
}

func (db *DBConn) AddLabel(lid int, label string) int64 {
	db.LabLock.Lock()
	if db.label == nil || len(db.label) <= 0 {
		db.label = make(map[int]string)
	}
	db.label[lid] = label
	db.LabLock.Unlock()

	res, err := db.getLabelIns().Exec(lid, label)
	if err != nil {
		log.Println(err)
		return 0
	}
	id, _ := res.LastInsertId()
	return id
}

// 修复下载失败的图片
func (db *DBConn) getPicsFix() *sql.Stmt {
	if _, ok := db.preStmt["picsFix"]; !ok {
		log.Println("【getPicsFix】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE pics SET `down`=0 WHERE `mark`=?"); err == nil {
			db.preStmt["picsFix"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["picsFix"]
}

func (db *DBConn) UpdatePicFix(mark string) {
	_, err := db.getPicsFix().Exec(mark)
	if err != nil {
		log.Println(err)
		return
	}
	return
}

func (db *DBConn) getPicsFix2() *sql.Stmt {
	if _, ok := db.preStmt["picsFix2"]; !ok {
		log.Println("【getPicsFix2】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("UPDATE pics SET `down`=?,`url`=?,`mark`=? WHERE `mark`=?"); err == nil {
			db.preStmt["picsFix2"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["picsFix2"]
}

func (db *DBConn) UpdatePicFix2(down int, url, mark, remark string) {
	_, err := db.getPicsFix2().Exec(down, url, remark, mark)
	if err != nil {
		log.Println(err)
		return
	}
	return
}

// 获取未修复图片的电影
func (db *DBConn) getMoviesUnfixed() *sql.Stmt {
	if _, ok := db.preStmt["movieUnfixed"]; !ok {
		log.Println("【getMoviesUnfixed】")
		conn := db.getConn()
		if stmt, err := conn.Prepare("SELECT `cid` FROM movies WHERE `id`>=? ORDER BY id LIMIT 3000"); err == nil {
			db.preStmt["movieUnfixed"] = stmt
		} else {
			panic(err.Error())
		}
	}
	return db.preStmt["movieUnfixed"]
}
func (db *DBConn) GetFixMovies(count int) (res []string) {
	rows, err := db.getMoviesUnfixed().Query(count)
	if err != nil {
		//log.Println(err)
		return
	}

	var cid string
	for rows.Next() {
		rows.Scan(&cid)
		res = append(res, cid)
	}
	return
}
